package com.lry.pda.bottom.c.backend;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class CLibCall {
    private Set<String> apiSet;

    private CLibCall() {
        apiSet = new HashSet<>();
        apiSet.add("printf");
        apiSet.add("power");
        apiSet.add("malloc");
    }
    private static CLibCall self = null;

    public static CLibCall getSelf() {
        if (self == null) {
            self = new CLibCall();
        }
        return self;
    }

    public boolean isAPICall(String funcName) {
        return apiSet.contains(funcName);
    }

    public Object invokeAPI(String funcName) {
        switch (funcName) {

        case "printf":
            return handlePrintfCall();
        case "power":
            return handlePowerCall();
        case "malloc":
            return handleMallocCall();
        default:
            return null;
        }
    }

    private Object handleMallocCall() {
        List<Object> argsList = FuncArgHelper.getSelf().getFuncArgList(false);
        int size = (Integer)argsList.get(0);
        int addr = 0;
        if (size > 0) {
            MemoryHeap memHeap = MemoryHeap.getSelf();
            addr = memHeap.allocMem(size);
        }
        return addr;

    }

    private Object handlePowerCall(){
        List<Object> argsList = FuncArgHelper.getSelf().getFuncArgList(false);
        int val1 = (int) argsList.get(0);
        int val2 = (int) argsList.get(1);
        return Math.pow(val1,val2);
    }

    private Object handlePrintfCall() {
        List<Object> argsList = FuncArgHelper.getSelf().getFuncArgList(false);
        String argStr = (String)argsList.get(0);
        String formatStr = "";

        int i = 0;
        int argCount = 1;
        while (i < argStr.length()) {
            if (argStr.charAt(i) == '%' && i+1 < argStr.length() && 
                    argStr.charAt(i+1) == 'd') {
                i += 2;
                formatStr += argsList.get(argCount);
                argCount++;
            } else {
                formatStr += argStr.charAt(i);
                i++;
            }
        }

        System.out.println(formatStr);

        return null;
    }
}
